package com.app.util.web;

import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.app.util.object.FieldUtil;
import com.app.util.string.StringUtil;

@SuppressWarnings("unchecked")
public class RequestUtil { 

	public static void printHeaders(HttpServletRequest request) {
		Enumeration<String> enus = request.getHeaderNames();
		System.out.println("Header {");
		while (enus.hasMoreElements()) {
			String name = enus.nextElement();
			System.out.println("	" + name + "=" + request.getHeader(name));
		}
		System.out.println("}");
	}

	public static void printParams(HttpServletRequest request) {
		Map<String, String[]> map = request.getParameterMap();
		System.out.println("Parameter {");
		for (Entry<String, String[]> ent : map.entrySet()) {
			System.out.println("	" + ent.getKey() + "=" + StringUtil.linkString(ent.getValue(), ", "));
		}
		System.out.println("}");
	}

	public static List<String> getParameterNameList(HttpServletRequest request) {
		Enumeration<String> enums = request.getParameterNames();
		List<String> list = new LinkedList<String>();
		while (enums.hasMoreElements()) {
			list.add(enums.nextElement());
		}
		return list;
	}

	public static Object getWebAttribute(HttpServletRequest request, String fullname) {
		String first = StringUtil.getLeft(fullname, ".");
		if (null != first) {
			if (first.equals("request")) {
				return getAttribute(request, fullname);
			} else if (first.equals("session")) {
				return getAttribute(request.getSession(), fullname);
			} else if (first.equals("application")) {
				return getAttribute(request.getSession().getServletContext(), fullname);
			}
		}
		Object o = null;
		if (null == fullname//
				|| null != (o = getAttribute(request, fullname)) //
				|| null != (o = getAttribute(request.getSession(), fullname))//
				|| null != (o = getAttribute(request.getSession().getServletContext(), fullname)))
			;

		return o;
	}

	public static Object getAttribute(HttpServletRequest request, String fullname) {
		if (null == fullname) {
			return null;
		}
		Object o = request.getAttribute(fullname);
		if (null == o) {
			if (fullname.indexOf('.') > -1) {
				Object obj = getAttribute(request, StringUtil.getLeft(fullname, "."));
				if (null == obj) {
					return null;
				}
				return FieldUtil.get(obj, StringUtil.getRightOuter(fullname, "."));
			}
		}
		return o;
	}

	public static Object getAttribute(HttpSession session, String fullname) {
		if (null == fullname) {
			return null;
		}
		Object o = session.getAttribute(fullname);
		if (null == o) {
			if (fullname.indexOf('.') > -1) {
				Object obj = getAttribute(session, StringUtil.getLeft(fullname, "."));
				if (null == obj) {
					return null;
				}
				return FieldUtil.get(obj, StringUtil.getRightOuter(fullname, "."));
			}
		}
		return o;
	}

	public static Object getAttribute(ServletContext servletContext, String fullname) {
		if (null == fullname) {
			return null;
		}
		Object o = servletContext.getAttribute(fullname);
		if (null == o) {
			if (fullname.indexOf('.') > -1) {
				Object obj = getAttribute(servletContext, StringUtil.getLeft(fullname, "."));
				if (null == obj) {
					return null;
				}
				return FieldUtil.get(obj, StringUtil.getRightOuter(fullname, "."));
			}
		}
		return o;
	}

	public static void fillObjectFromParams(HttpServletRequest request, Object obj) {
		Enumeration<String> enums = request.getParameterNames();
		while (enums.hasMoreElements()) {
			String name = enums.nextElement();
			Class<?> type = FieldUtil.propertyType(obj.getClass(), name);
			if (null == type) {
				continue;
			}
			Object value = null;
			if (type.isArray()) {
				value = request.getParameterValues(name);
			} else {
				value = request.getParameter(name);
			}
			FieldUtil.set(obj, name, value);
		}
	}

	public static void setAttributeFromObject(Object obj, HttpServletRequest request) {
		String[] getters = FieldUtil.getters(obj.getClass(), null);
		for (String getter : getters) {
			try {
				request.setAttribute(getter, FieldUtil.get(obj, getter));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 得到请求的实际IP，但是无法确定是否作弊。<br />
	 * 取得过程: 1.x-forwarded-for -> 2.Proxy-Client-IP -> 3.WL-Proxy-Client-IP ->
	 * 4.request.getRemoteAddr()
	 * 
	 * @param request
	 * @return
	 */
	public static String getRealIP(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}
}
